using System;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Xml;
using System.Xml.Serialization;
using SubSonic;
using SubSonic.Utilities;
namespace Impact.Model.Objects
{
    /// <summary>
    /// Strongly-typed collection for the Article class.
    /// </summary>
    [Serializable]
    public partial class ArticleCollection : ActiveList<Article, ArticleCollection>
    {
        public ArticleCollection() { }
    }
    /// <summary>
    /// This is an ActiveRecord class which wraps the impact_Articles table.
    /// </summary>
    [Serializable]
    public partial class Article : ActiveRecord<Article>, IActiveRecord
    {
        #region .ctors and Default Settings

        public Article()
        {
            SetSQLProps();
            InitSetDefaults();
            MarkNew();
        }

        private void InitSetDefaults() { SetDefaults(); }

        public Article( bool useDatabaseDefaults )
        {
            SetSQLProps();
            if ( useDatabaseDefaults )
                ForceDefaults();
            MarkNew();
        }

        public Article( object keyID )
        {
            SetSQLProps();
            InitSetDefaults();
            LoadByKey( keyID );
        }

        public Article( string columnName, object columnValue )
        {
            SetSQLProps();
            InitSetDefaults();
            LoadByParam( columnName, columnValue );
        }

        protected static void SetSQLProps() { GetTableSchema(); }

        #endregion

        #region Schema and Query Accessor
        public static Query CreateQuery() { return new Query( Schema ); }
        public static TableSchema.Table Schema
        {
            get
            {
                if ( BaseSchema == null )
                    SetSQLProps();
                return BaseSchema;
            }
        }

        private static void GetTableSchema()
        {
            if ( !IsSchemaInitialized )
            {
                //Schema declaration
                TableSchema.Table schema = new TableSchema.Table( "impact_Articles", TableType.Table, DataService.GetInstance( "ImpactProvider" ) );
                schema.Columns = new TableSchema.TableColumnCollection();
                schema.SchemaName = @"dbo";
                //columns

                TableSchema.TableColumn colvarArticleId = new TableSchema.TableColumn( schema );
                colvarArticleId.ColumnName = "ArticleId";
                colvarArticleId.DataType = DbType.Int32;
                colvarArticleId.MaxLength = 0;
                colvarArticleId.AutoIncrement = true;
                colvarArticleId.IsNullable = false;
                colvarArticleId.IsPrimaryKey = true;
                colvarArticleId.IsForeignKey = false;
                colvarArticleId.IsReadOnly = false;
                colvarArticleId.DefaultSetting = @"";
                colvarArticleId.ForeignKeyTableName = "";
                schema.Columns.Add( colvarArticleId );

                TableSchema.TableColumn colvarCategoryId = new TableSchema.TableColumn( schema );
                colvarCategoryId.ColumnName = "CategoryId";
                colvarCategoryId.DataType = DbType.Int32;
                colvarCategoryId.MaxLength = 0;
                colvarCategoryId.AutoIncrement = false;
                colvarCategoryId.IsNullable = false;
                colvarCategoryId.IsPrimaryKey = false;
                colvarCategoryId.IsForeignKey = true;
                colvarCategoryId.IsReadOnly = false;
                colvarCategoryId.DefaultSetting = @"";

                colvarCategoryId.ForeignKeyTableName = "impact_ArticleCategories";
                schema.Columns.Add( colvarCategoryId );

                TableSchema.TableColumn colvarTitle = new TableSchema.TableColumn( schema );
                colvarTitle.ColumnName = "Title";
                colvarTitle.DataType = DbType.AnsiString;
                colvarTitle.MaxLength = 50;
                colvarTitle.AutoIncrement = false;
                colvarTitle.IsNullable = false;
                colvarTitle.IsPrimaryKey = false;
                colvarTitle.IsForeignKey = false;
                colvarTitle.IsReadOnly = false;
                colvarTitle.DefaultSetting = @"";
                colvarTitle.ForeignKeyTableName = "";
                schema.Columns.Add( colvarTitle );

                TableSchema.TableColumn colvarBody = new TableSchema.TableColumn( schema );
                colvarBody.ColumnName = "Body";
                colvarBody.DataType = DbType.AnsiString;
                colvarBody.MaxLength = 2147483647;
                colvarBody.AutoIncrement = false;
                colvarBody.IsNullable = true;
                colvarBody.IsPrimaryKey = false;
                colvarBody.IsForeignKey = false;
                colvarBody.IsReadOnly = false;
                colvarBody.DefaultSetting = @"";
                colvarBody.ForeignKeyTableName = "";
                schema.Columns.Add( colvarBody );

                TableSchema.TableColumn colvarEnabled = new TableSchema.TableColumn( schema );
                colvarEnabled.ColumnName = "Enabled";
                colvarEnabled.DataType = DbType.Boolean;
                colvarEnabled.MaxLength = 0;
                colvarEnabled.AutoIncrement = false;
                colvarEnabled.IsNullable = false;
                colvarEnabled.IsPrimaryKey = false;
                colvarEnabled.IsForeignKey = false;
                colvarEnabled.IsReadOnly = false;

                colvarEnabled.DefaultSetting = @"((0))";
                colvarEnabled.ForeignKeyTableName = "";
                schema.Columns.Add( colvarEnabled );

                TableSchema.TableColumn colvarAllowComments = new TableSchema.TableColumn( schema );
                colvarAllowComments.ColumnName = "AllowComments";
                colvarAllowComments.DataType = DbType.Boolean;
                colvarAllowComments.MaxLength = 0;
                colvarAllowComments.AutoIncrement = false;
                colvarAllowComments.IsNullable = false;
                colvarAllowComments.IsPrimaryKey = false;
                colvarAllowComments.IsForeignKey = false;
                colvarAllowComments.IsReadOnly = false;

                colvarAllowComments.DefaultSetting = @"((0))";
                colvarAllowComments.ForeignKeyTableName = "";
                schema.Columns.Add( colvarAllowComments );

                TableSchema.TableColumn colvarUserViews = new TableSchema.TableColumn( schema );
                colvarUserViews.ColumnName = "UserViews";
                colvarUserViews.DataType = DbType.Int32;
                colvarUserViews.MaxLength = 0;
                colvarUserViews.AutoIncrement = false;
                colvarUserViews.IsNullable = false;
                colvarUserViews.IsPrimaryKey = false;
                colvarUserViews.IsForeignKey = false;
                colvarUserViews.IsReadOnly = false;

                colvarUserViews.DefaultSetting = @"((0))";
                colvarUserViews.ForeignKeyTableName = "";
                schema.Columns.Add( colvarUserViews );

                TableSchema.TableColumn colvarCreatedOn = new TableSchema.TableColumn( schema );
                colvarCreatedOn.ColumnName = "CreatedOn";
                colvarCreatedOn.DataType = DbType.DateTime;
                colvarCreatedOn.MaxLength = 0;
                colvarCreatedOn.AutoIncrement = false;
                colvarCreatedOn.IsNullable = false;
                colvarCreatedOn.IsPrimaryKey = false;
                colvarCreatedOn.IsForeignKey = false;
                colvarCreatedOn.IsReadOnly = false;
                colvarCreatedOn.DefaultSetting = @"";
                colvarCreatedOn.ForeignKeyTableName = "";
                schema.Columns.Add( colvarCreatedOn );

                TableSchema.TableColumn colvarCreatedBy = new TableSchema.TableColumn( schema );
                colvarCreatedBy.ColumnName = "CreatedBy";
                colvarCreatedBy.DataType = DbType.String;
                colvarCreatedBy.MaxLength = 50;
                colvarCreatedBy.AutoIncrement = false;
                colvarCreatedBy.IsNullable = false;
                colvarCreatedBy.IsPrimaryKey = false;
                colvarCreatedBy.IsForeignKey = false;
                colvarCreatedBy.IsReadOnly = false;
                colvarCreatedBy.DefaultSetting = @"";
                colvarCreatedBy.ForeignKeyTableName = "";
                schema.Columns.Add( colvarCreatedBy );

                TableSchema.TableColumn colvarModifiedOn = new TableSchema.TableColumn( schema );
                colvarModifiedOn.ColumnName = "ModifiedOn";
                colvarModifiedOn.DataType = DbType.DateTime;
                colvarModifiedOn.MaxLength = 0;
                colvarModifiedOn.AutoIncrement = false;
                colvarModifiedOn.IsNullable = true;
                colvarModifiedOn.IsPrimaryKey = false;
                colvarModifiedOn.IsForeignKey = false;
                colvarModifiedOn.IsReadOnly = false;
                colvarModifiedOn.DefaultSetting = @"";
                colvarModifiedOn.ForeignKeyTableName = "";
                schema.Columns.Add( colvarModifiedOn );

                TableSchema.TableColumn colvarModifiedBy = new TableSchema.TableColumn( schema );
                colvarModifiedBy.ColumnName = "ModifiedBy";
                colvarModifiedBy.DataType = DbType.String;
                colvarModifiedBy.MaxLength = 50;
                colvarModifiedBy.AutoIncrement = false;
                colvarModifiedBy.IsNullable = true;
                colvarModifiedBy.IsPrimaryKey = false;
                colvarModifiedBy.IsForeignKey = false;
                colvarModifiedBy.IsReadOnly = false;
                colvarModifiedBy.DefaultSetting = @"";
                colvarModifiedBy.ForeignKeyTableName = "";
                schema.Columns.Add( colvarModifiedBy );

                TableSchema.TableColumn colvarIsDeleted = new TableSchema.TableColumn( schema );
                colvarIsDeleted.ColumnName = "IsDeleted";
                colvarIsDeleted.DataType = DbType.Boolean;
                colvarIsDeleted.MaxLength = 0;
                colvarIsDeleted.AutoIncrement = false;
                colvarIsDeleted.IsNullable = false;
                colvarIsDeleted.IsPrimaryKey = false;
                colvarIsDeleted.IsForeignKey = false;
                colvarIsDeleted.IsReadOnly = false;

                colvarIsDeleted.DefaultSetting = @"((0))";
                colvarIsDeleted.ForeignKeyTableName = "";
                schema.Columns.Add( colvarIsDeleted );

                BaseSchema = schema;
                //add this schema to the provider
                //so we can query it later
                DataService.Providers["ImpactProvider"].AddSchema( "impact_Articles", schema );
            }
        }
        #endregion

        #region Props

        [XmlAttribute( "ArticleId" )]
        [Bindable( true )]
        public int ArticleId
        {
            get { return GetColumnValue<int>( Columns.ArticleId ); }
            set { SetColumnValue( Columns.ArticleId, value ); }
        }

        [XmlAttribute( "CategoryId" )]
        [Bindable( true )]
        public int CategoryId
        {
            get { return GetColumnValue<int>( Columns.CategoryId ); }
            set { SetColumnValue( Columns.CategoryId, value ); }
        }

        [XmlAttribute( "Title" )]
        [Bindable( true )]
        public string Title
        {
            get { return GetColumnValue<string>( Columns.Title ); }
            set { SetColumnValue( Columns.Title, value ); }
        }

        [XmlAttribute( "Body" )]
        [Bindable( true )]
        public string Body
        {
            get { return GetColumnValue<string>( Columns.Body ); }
            set { SetColumnValue( Columns.Body, value ); }
        }

        [XmlAttribute( "Enabled" )]
        [Bindable( true )]
        public bool Enabled
        {
            get { return GetColumnValue<bool>( Columns.Enabled ); }
            set { SetColumnValue( Columns.Enabled, value ); }
        }

        [XmlAttribute( "AllowComments" )]
        [Bindable( true )]
        public bool AllowComments
        {
            get { return GetColumnValue<bool>( Columns.AllowComments ); }
            set { SetColumnValue( Columns.AllowComments, value ); }
        }

        [XmlAttribute( "UserViews" )]
        [Bindable( true )]
        public int UserViews
        {
            get { return GetColumnValue<int>( Columns.UserViews ); }
            set { SetColumnValue( Columns.UserViews, value ); }
        }

        [XmlAttribute( "CreatedOn" )]
        [Bindable( true )]
        public DateTime CreatedOn
        {
            get { return GetColumnValue<DateTime>( Columns.CreatedOn ); }
            set { SetColumnValue( Columns.CreatedOn, value ); }
        }

        [XmlAttribute( "CreatedBy" )]
        [Bindable( true )]
        public string CreatedBy
        {
            get { return GetColumnValue<string>( Columns.CreatedBy ); }
            set { SetColumnValue( Columns.CreatedBy, value ); }
        }

        [XmlAttribute( "ModifiedOn" )]
        [Bindable( true )]
        public DateTime? ModifiedOn
        {
            get { return GetColumnValue<DateTime?>( Columns.ModifiedOn ); }
            set { SetColumnValue( Columns.ModifiedOn, value ); }
        }

        [XmlAttribute( "ModifiedBy" )]
        [Bindable( true )]
        public string ModifiedBy
        {
            get { return GetColumnValue<string>( Columns.ModifiedBy ); }
            set { SetColumnValue( Columns.ModifiedBy, value ); }
        }

        [XmlAttribute( "IsDeleted" )]
        [Bindable( true )]
        public bool IsDeleted
        {
            get { return GetColumnValue<bool>( Columns.IsDeleted ); }
            set { SetColumnValue( Columns.IsDeleted, value ); }
        }

        #endregion


        #region PrimaryKey Methods

        protected override void SetPrimaryKey( object oValue )
        {
            base.SetPrimaryKey( oValue );

            SetPKValues();
        }


        private Impact.Model.Objects.ArticleCommentCollection colArticleComments;
        public Impact.Model.Objects.ArticleCommentCollection ArticleComments
        {
            get
            {
                if ( colArticleComments == null )
                {
                    colArticleComments = new Impact.Model.Objects.ArticleCommentCollection().Where( ArticleComment.Columns.ArticleId, ArticleId ).Load();
                    colArticleComments.ListChanged += new ListChangedEventHandler( colArticleComments_ListChanged );
                }
                return colArticleComments;
            }
            set
            {
                colArticleComments = value;
                colArticleComments.ListChanged += new ListChangedEventHandler( colArticleComments_ListChanged );
            }
        }

        void colArticleComments_ListChanged( object sender, ListChangedEventArgs e )
        {
            if ( e.ListChangedType == ListChangedType.ItemAdded )
            {
                // Set foreign key value
                colArticleComments[e.NewIndex].ArticleId = ArticleId;
            }
        }

        private Impact.Model.Objects.ArticleTagCollection colArticleTags;
        public Impact.Model.Objects.ArticleTagCollection ArticleTags
        {
            get
            {
                if ( colArticleTags == null )
                {
                    colArticleTags = new Impact.Model.Objects.ArticleTagCollection().Where( ArticleTag.Columns.ArticleId, ArticleId ).Load();
                    colArticleTags.ListChanged += new ListChangedEventHandler( colArticleTags_ListChanged );
                }
                return colArticleTags;
            }
            set
            {
                colArticleTags = value;
                colArticleTags.ListChanged += new ListChangedEventHandler( colArticleTags_ListChanged );
            }
        }

        void colArticleTags_ListChanged( object sender, ListChangedEventArgs e )
        {
            if ( e.ListChangedType == ListChangedType.ItemAdded )
            {
                // Set foreign key value
                colArticleTags[e.NewIndex].ArticleId = ArticleId;
            }
        }

        #endregion



        #region ForeignKey Properties

        /// <summary>
        /// Returns a ArticleCategory ActiveRecord object related to this Article
        /// 
        /// </summary>
        public Impact.Model.Objects.ArticleCategory ArticleCategory
        {
            get { return Impact.Model.Objects.ArticleCategory.FetchByID( this.CategoryId ); }
            set { SetColumnValue( "CategoryId", value.CategoryId ); }
        }


        #endregion



        #region Many To Many Helpers


        public Impact.Model.Objects.TagCollection GetTagCollection() { return Article.GetTagCollection( this.ArticleId ); }
        public static Impact.Model.Objects.TagCollection GetTagCollection( int varArticleId )
        {
            SubSonic.QueryCommand cmd = new SubSonic.QueryCommand( "SELECT * FROM [dbo].[impact_Tags] INNER JOIN [impact_ArticleTags] ON [impact_Tags].[TagId] = [impact_ArticleTags].[TagId] WHERE [impact_ArticleTags].[ArticleId] = @ArticleId", Article.Schema.Provider.Name );
            cmd.AddParameter( "@ArticleId", varArticleId, DbType.Int32 );
            IDataReader rdr = SubSonic.DataService.GetReader( cmd );
            TagCollection coll = new TagCollection();
            coll.LoadAndCloseReader( rdr );
            return coll;
        }

        #endregion



        #region ObjectDataSource support


        /// <summary>
        /// Inserts a record, can be used with the Object Data Source
        /// </summary>
        public static void Insert( int varCategoryId, string varTitle, string varBody, bool varEnabled, bool varAllowComments, int varUserViews, DateTime varCreatedOn, string varCreatedBy, DateTime? varModifiedOn, string varModifiedBy, bool varIsDeleted )
        {
            Article item = new Article();

            item.CategoryId = varCategoryId;

            item.Title = varTitle;

            item.Body = varBody;

            item.Enabled = varEnabled;

            item.AllowComments = varAllowComments;

            item.UserViews = varUserViews;

            item.CreatedOn = varCreatedOn;

            item.CreatedBy = varCreatedBy;

            item.ModifiedOn = varModifiedOn;

            item.ModifiedBy = varModifiedBy;

            item.IsDeleted = varIsDeleted;


            if ( System.Web.HttpContext.Current != null )
                item.Save( System.Web.HttpContext.Current.User.Identity.Name );
            else
                item.Save( System.Threading.Thread.CurrentPrincipal.Identity.Name );
        }

        /// <summary>
        /// Updates a record, can be used with the Object Data Source
        /// </summary>
        public static void Update( int varArticleId, int varCategoryId, string varTitle, string varBody, bool varEnabled, bool varAllowComments, int varUserViews, DateTime varCreatedOn, string varCreatedBy, DateTime? varModifiedOn, string varModifiedBy, bool varIsDeleted )
        {
            Article item = new Article();

            item.ArticleId = varArticleId;

            item.CategoryId = varCategoryId;

            item.Title = varTitle;

            item.Body = varBody;

            item.Enabled = varEnabled;

            item.AllowComments = varAllowComments;

            item.UserViews = varUserViews;

            item.CreatedOn = varCreatedOn;

            item.CreatedBy = varCreatedBy;

            item.ModifiedOn = varModifiedOn;

            item.ModifiedBy = varModifiedBy;

            item.IsDeleted = varIsDeleted;

            item.IsNew = false;
            if ( System.Web.HttpContext.Current != null )
                item.Save( System.Web.HttpContext.Current.User.Identity.Name );
            else
                item.Save( System.Threading.Thread.CurrentPrincipal.Identity.Name );
        }
        #endregion



        #region Typed Columns


        public static TableSchema.TableColumn ArticleIdColumn
        {
            get { return Schema.Columns[0]; }
        }



        public static TableSchema.TableColumn CategoryIdColumn
        {
            get { return Schema.Columns[1]; }
        }



        public static TableSchema.TableColumn TitleColumn
        {
            get { return Schema.Columns[2]; }
        }



        public static TableSchema.TableColumn BodyColumn
        {
            get { return Schema.Columns[3]; }
        }



        public static TableSchema.TableColumn EnabledColumn
        {
            get { return Schema.Columns[4]; }
        }



        public static TableSchema.TableColumn AllowCommentsColumn
        {
            get { return Schema.Columns[5]; }
        }



        public static TableSchema.TableColumn UserViewsColumn
        {
            get { return Schema.Columns[6]; }
        }



        public static TableSchema.TableColumn CreatedOnColumn
        {
            get { return Schema.Columns[7]; }
        }



        public static TableSchema.TableColumn CreatedByColumn
        {
            get { return Schema.Columns[8]; }
        }



        public static TableSchema.TableColumn ModifiedOnColumn
        {
            get { return Schema.Columns[9]; }
        }



        public static TableSchema.TableColumn ModifiedByColumn
        {
            get { return Schema.Columns[10]; }
        }



        public static TableSchema.TableColumn IsDeletedColumn
        {
            get { return Schema.Columns[11]; }
        }



        #endregion
        #region Columns Struct
        public struct Columns
        {
            public static string ArticleId = @"ArticleId";
            public static string CategoryId = @"CategoryId";
            public static string Title = @"Title";
            public static string Body = @"Body";
            public static string Enabled = @"Enabled";
            public static string AllowComments = @"AllowComments";
            public static string UserViews = @"UserViews";
            public static string CreatedOn = @"CreatedOn";
            public static string CreatedBy = @"CreatedBy";
            public static string ModifiedOn = @"ModifiedOn";
            public static string ModifiedBy = @"ModifiedBy";
            public static string IsDeleted = @"IsDeleted";

        }
        #endregion

        #region Update PK Collections

        public void SetPKValues()
        {
            if ( colArticleComments != null )
            {
                foreach ( Impact.Model.Objects.ArticleComment item in colArticleComments )
                {
                    if ( item.ArticleId != ArticleId )
                    {
                        item.ArticleId = ArticleId;
                    }
                }
            }

            if ( colArticleTags != null )
            {
                foreach ( Impact.Model.Objects.ArticleTag item in colArticleTags )
                {
                    if ( item.ArticleId != ArticleId )
                    {
                        item.ArticleId = ArticleId;
                    }
                }
            }
        }
        #endregion

        #region Deep Save

        public void DeepSave()
        {
            Save();

            if ( colArticleComments != null )
            {
                colArticleComments.SaveAll();
            }
        }
        #endregion
    }
}
